package net.baipeng.bp_aliyun_push;

import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;

import com.alibaba.sdk.android.push.CloudPushService;
import com.alibaba.sdk.android.push.CommonCallback;
import com.alibaba.sdk.android.push.huawei.HuaWeiRegister;
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
import com.alibaba.sdk.android.push.register.MeizuRegister;
import com.alibaba.sdk.android.push.register.MiPushRegister;
import com.alibaba.sdk.android.push.register.OppoRegister;
import com.alibaba.sdk.android.push.register.VivoRegister;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

public class BpAliyunPushPlugin implements FlutterPlugin, MethodCallHandler {

    public static final String TAG = "BpAliyunPushPlugin";

    private MethodChannel channel;

    public static FlutterPushNotification launchNotification;

    /**
     * 该方法必须在Appcation onCreate中被执行，否则推送会有问题
     */
    public static void initPush(Application application) {
        Log.i(TAG, "initPush");
        PushServiceFactory.init(application.getApplicationContext());
        final CloudPushService pushService = PushServiceFactory.getCloudPushService();
        pushService.register(application.getApplicationContext(), new CommonCallback() {
            @Override
            public void onSuccess(String response) {
                Log.i(TAG, "init cloudChannel success --- deviceId:" + pushService.getDeviceId());
            }

            @Override
            public void onFailed(String errorCode, String errorMessage) {
                Log.i(TAG, "init cloudChannel failed -- errorCode:" + errorCode + " -- errorMessage:" + errorMessage);
            }
        });

        initThirdPush(application);
    }

    public static void initThirdPush(Application application) {
        Log.i(TAG, "initThirdPush");
        ApplicationInfo appInfo = null;
        try {
            appInfo = application
                    .getApplicationContext()
                    .getPackageManager()
                    .getApplicationInfo(application.getApplicationContext().getPackageName(),
                            PackageManager.GET_META_DATA);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        if (appInfo == null) {
            return;
        }

        String pushChannelId = appInfo.metaData.getString("com.flutter.push.channelId");
        String pushChannelName = appInfo.metaData.getString("com.flutter.push.channelName");
        String pushChannelDescription = appInfo.metaData.getString("com.flutter.push.channelDescription");
        createNotificationChannel(application.getApplicationContext(), pushChannelId, pushChannelName, pushChannelDescription);

        ThirdPushConfig config = new ThirdPushConfig();
        config.miPushAppId = appInfo.metaData.getString("com.mi.push.app_id");
        config.miPushAppKey = appInfo.metaData.getString("com.mi.push.api_key");
        config.huaweiPushAppId = appInfo.metaData.getString("com.huawei.hms.client.appid");
        config.oppoPushAppKey = appInfo.metaData.getString("com.oppo.push.api_key");
        config.oppoPushAppSecret = appInfo.metaData.getString("com.oppo.push.app_secret");
        config.vivoPushAppId = appInfo.metaData.getString("com.vivo.push.app_id");
        config.vivoPushAppKey = appInfo.metaData.getString("com.vivo.push.api_key");
        config.meizhuPushAppId = appInfo.metaData.getString("com.meizhu.push.app_id");
        config.meizhuPushAppKey = appInfo.metaData.getString("com.meizhu.push.api_key");

        // 注册方法会自动判断是否支持小米系统推送，如不支持会跳过注册。
        if (!TextUtils.isEmpty(config.miPushAppId) && !TextUtils.isEmpty(config.miPushAppKey)) {
            Log.i(TAG, "注册小米推送服务...");
            MiPushRegister.register(application.getApplicationContext(), config.miPushAppId, config.miPushAppKey);
        }
        // 注册方法会自动判断是否支持华为系统推送，如不支持会跳过注册。
        if (!TextUtils.isEmpty(config.huaweiPushAppId)) {
            Log.i(TAG, "注册华为推送服务...");
            HuaWeiRegister.register(application);
        }
        // OPPO通道注册
        if (!TextUtils.isEmpty(config.oppoPushAppKey) && !TextUtils.isEmpty(config.oppoPushAppSecret)) {
            Log.i(TAG, "注册OPPO推送服务...");
            OppoRegister.register(application.getApplicationContext(), config.oppoPushAppKey, config.oppoPushAppSecret); // appKey/appSecret在OPPO开发者平台获取
        }
        // VIVO通道注册
        if (!TextUtils.isEmpty(config.vivoPushAppId) && !TextUtils.isEmpty(config.vivoPushAppKey)) {
            Log.i(TAG, "注册VIVO推送服务...");
            VivoRegister.register(application.getApplicationContext());
        }
        // 魅族通道注册
        if (!TextUtils.isEmpty(config.meizhuPushAppId) && !TextUtils.isEmpty(config.meizhuPushAppKey)) {
            Log.i(TAG, "注册魅族推送服务...");
            MeizuRegister.register(application.getApplicationContext(), config.meizhuPushAppId, config.meizhuPushAppKey); // appId/appkey在魅族开发者平台获取
        }

//        GcmRegister.register(application.getApplicationContext(), "send_id", "application_id");
    }

    private static void createNotificationChannel(Context context, String channelId, String channelName, String channelDescription) {
        Log.i(TAG, "createNotificationChannel channelId:" + channelId + " channelName:" + channelName + " channelDescription:" + channelDescription);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            // 通知渠道的id
//            String id = channelId;
            // 用户可以看到的通知渠道的名字.
//            CharSequence name = channelName;
            // 用户可以看到的通知渠道的描述
//            String description = channelDescription;
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel mChannel = new NotificationChannel(channelId, channelName, importance);
            // 配置通知渠道的属性
            mChannel.setDescription(channelDescription);
            // 设置通知出现时的闪灯（如果 android 设备支持的话）
            mChannel.enableLights(true);
            mChannel.setLightColor(Color.RED);
            // 设置通知出现时的震动（如果 android 设备支持的话）
            mChannel.enableVibration(true);
            mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
            //最后在notificationManager中创建该通知渠道
            mNotificationManager.createNotificationChannel(mChannel);
        }
    }

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
        Log.i(TAG, "onAttachedToEngine");
        channel = new MethodChannel(binding.getBinaryMessenger(), "bp_aliyun_push");
        channel.setMethodCallHandler(this);
        EventBus.getDefault().register(this);
    }

    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        Log.i(TAG, "onDetachedFromEngine");
        EventBus.getDefault().unregister(this);
        channel.setMethodCallHandler(null);
        channel = null;
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
        Log.i(TAG, "onMethodCall:" + call.method);
        switch (call.method) {
            case "getPlatformVersion":
                result.success("Android " + Build.VERSION.RELEASE);
                break;
            case "getLaunchNotification":
                result.success(launchNotification.getParamsJSONString());
                break;
            case "bindAccount":
                bindAccount(call);
                result.success(true);
                break;
            case "unbindAccount":
                unbindAccount();
                result.success(true);
                break;
            case "rebindAccount":
                rebindAccount(call);
                result.success(true);
                break;
            default:
                result.notImplemented();
                break;
        }
    }

    public void bindAccount(@NonNull MethodCall call) {
        String account = (String) call.arguments;
        CloudPushService pushService = PushServiceFactory.getCloudPushService();
        pushService.bindAccount(account, null);
    }

    public void unbindAccount() {
        CloudPushService pushService = PushServiceFactory.getCloudPushService();
        pushService.unbindAccount(null);
    }

    public void rebindAccount(@NonNull MethodCall call) {
        final MethodCall aCall = call;
        CloudPushService pushService = PushServiceFactory.getCloudPushService();
        pushService.unbindAccount(new CommonCallback() {
            @Override
            public void onSuccess(String s) {
                bindAccount(aCall);
            }

            @Override
            public void onFailed(String s, String s1) {

            }
        });
    }

    @Subscribe()
    public void onMessageEvent(PushMessageEvent event) {
        Log.i(BpAliyunPushPlugin.TAG, "onMessageEvent:" + event.eventName);
        if (channel == null) {
            return;
        }
        if (PushMessageEvent.EVENT_onReceiverMessage.equals(event.eventName)
                || PushMessageEvent.EVENT_onReceiverNotification.equals(event.eventName)) {
            //接受消息
            channel.invokeMethod(event.eventName, event.getParamsJSONString());
        }
    }


    public static void sendPushNotification(FlutterPushNotification message) {
        EventBus.getDefault().post(new PushMessageEvent(PushMessageEvent.EVENT_onReceiverNotification, message));
    }

    public static void sendPushMessage(FlutterPushMessage message) {
        EventBus.getDefault().post(new PushMessageEvent(PushMessageEvent.EVENT_onReceiverMessage, message));
    }
}
